package Texas;

import Texas.Card.*;
import Texas.Round.*;

import java.util.*;

public class Table {
	private ArrayList<Player> _players;
	private ArrayList<Card> _communityCards;
	private DealerButton _dealerButton;
	private int _bigBlind = 10, _captial = 1000;
	
	public Table(Player owner, int countOfPlayers) {
		_players = new ArrayList<Player>();
		_communityCards = new ArrayList<Card>(); 

		_players.add(owner);
		for(int i = 0; i < countOfPlayers; i++) {
			if(i != 0)
				_players.add(new Player("Computer "+i));
			_players.get(i).setChips(_captial);
		}

		CardDeck.getInstance().shuffle();
	}
	
	private void looseDealerButton() {
		int j = 0;
		
		// Jeder spieler erhält eine Karte
		dealCards(1);
	
		// Das eigentliche auslosen des DealerButton
		for(int i = 1; i < _players.size(); i++) {
			if(_players.get(j).getCard(0).getRank() == _players.get(i).getCard(0).getRank()) {
				if(_players.get(j).getCard(0).getSuit().getValue() < _players.get(i).getCard(0).getSuit().getValue())
					j = i;
			}
			else if(_players.get(j).getCard(0).getRank().getValue() < _players.get(i).getCard(0).getRank().getValue())
				j = i;
		}
		
		// Karten werden zurückgelegt
		collectCards();
		
		_dealerButton = new DealerButton(_players.get(j));
	}
	
	private void moveDealerButton() {		
		for(int i = 1; i <= _players.size(); i++) {
			Player player = _players.get((_players.indexOf(_dealerButton.getPlayer())+i)%_players.size());
			if(player.getChips() > 0) {
				_dealerButton.setPlayer(player);
				break;
			}
		}
	}
		
	public DealerButton getDealerButton() {
		return _dealerButton;
	}
	
	public void dealCards(int count) {
		int n[] = new int[9];
		n[0]++;
		n[1]++;
		if(count >= 1 && count <= 3) {
			for(int i = 0; i < count; i++) {
				n[2]++;
				n[3]++;
				if((count == 1 && _communityCards.isEmpty()) || (count == 2 && _communityCards.isEmpty())) {
					for(int j = 0; j < _players.size(); j++) {
						n[4]++;
						_players.get(j).addCard(CardDeck.getInstance().pop());
						n[5]++;
					}
					n[4]++;
				} else if(count == 1 || count == 3) {
					n[6]++;
					_communityCards.add(CardDeck.getInstance().pop());
					n[7]++;
				}
			}
			n[2]++;
		}
		n[8]++;
		
		System.out.println("WBT DealCards");
		for(int i = 0; i < n.length; i++)
			System.out.println("n["+i+"] = " + n[i]);
	}

	public void collectCards() {
		for (Player player : _players)
			player.clearCardSet();
		
		CardDeck.getInstance().shuffle();
	}
	
	public int getBigBlind() {
		return _bigBlind;
	}
	
	public void demandBlinds() {
		if(_players.size() > 2) {
			_players.get((_players.indexOf(getDealerButton().getPlayer())+1)%_players.size()).payBlinds(_bigBlind/2);
			_players.get((_players.indexOf(getDealerButton().getPlayer())+2)%_players.size()).payBlinds(_bigBlind);
		} else {
			getDealerButton().getPlayer().payBlinds(_bigBlind/2);
			_players.get((_players.indexOf(getDealerButton().getPlayer())+1)%_players.size()).payBlinds(_bigBlind);
		}
	}

	public void start() {
		looseDealerButton();

		while(_players.size() > 1) {
			for(RoundType roundType : RoundType.values()) {
				IRound round = null;

				switch(roundType) {
				case PREFLOP: round = new PreFlop(this, _players); break;
				case FLOP: round = new Flop(this, _players); break;
				case TURN: round = new Turn(this, _players); break;
				case RIVER: round =  new River(this, _players); break;
				}
				round.start();
				
				for(Player player : _players)
					player.clearDediction();
				
				if(round.getEarlyWinner() != null) {
					payOut(round.getEarlyWinner());
					break;
				} else if(round.getEarlyWinner() == null && roundType == RoundType.RIVER) {
					Showdown showdown = new Showdown(this, _players);
					showdown.start();
					payOut(showdown.getWinner());
					System.out.println("\n"+showdown.getWinner().getName()+"\n");
				}
			}
			removePoorPlayers();
			if(_players.size() > 1) {
				moveDealerButton();
				_communityCards.clear();
				CardDeck.getInstance().shuffle();
			}
		}
	}
	
	private void payOut(Player player) {
		player.addChips(Pot.getInstance().getContent());
		Pot.getInstance().clearPot();
	}
	
	private void removePoorPlayers() {
		for(int i = 0; i < _players.size(); i++) {
			if(_players.get(i).getChips() == 0) {
				_players.remove(i);
				i--;
			} else {
				_players.get(i).clearCardSet();
				_players.get(i).clearStates();
			}
		}
	}
	
	public ArrayList<Card> getCommunityCards() {
		return _communityCards;
	}
	
	public void printCommuntiyCards() {
		System.out.printf("Gemeinschaftskarten: ");
		for(Card card : _communityCards)
			System.out.printf(" %s", card);
		System.out.printf("\n");		
	}
	
	public ArrayList<Player> getPlayers() {
		return _players;
	}
}
